package aexp.accel;

import android.app.Activity;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
import android.os.DeadObjectException;
import android.os.RemoteException;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;

public class Accel extends Activity
{
	static final String LOG_TAG = "ACCEL";
	static final String SAMPLING_SERVICE_ACTIVATED_KEY = "samplingServiceActivated";
	static final String WALKINGTEXT_KEY = "walkingTextKey";
	static final String RUNNINGTEXT_KEY = "runningTextKey";
	static final String SHAKINGTEXT_KEY = "shakingTextKey";

    /** Called when the activity is first created. */;
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
		Log.d( LOG_TAG, "onCreate" );
		if( savedInstanceState != null ) {
			samplingServiceActivated = savedInstanceState.getBoolean( SAMPLING_SERVICE_ACTIVATED_KEY, false );
			walkingText = savedInstanceState.getString( WALKINGTEXT_KEY );
			runningText = savedInstanceState.getString( RUNNINGTEXT_KEY );
			shakingText = savedInstanceState.getString( SHAKINGTEXT_KEY );
		} else
			samplingServiceActivated = false;

		bindSamplingService();
        setContentView(R.layout.main);
		walkingTV = (TextView)findViewById( R.id.tv_walking );
		runningTV = (TextView)findViewById( R.id.tv_running );
		shakingTV = (TextView)findViewById( R.id.tv_shaking );
		if( walkingText != null )
			walkingTV.setText( walkingText );
		if( runningText != null )
			runningTV.setText( runningText );
		if( shakingText != null )
			shakingTV.setText( shakingText );
		CheckBox cb = (CheckBox)findViewById( R.id.cb_sampling );
		cb.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
			public void onCheckedChanged(CompoundButton  buttonView, boolean isChecked) {
				if( isChecked ) {
					Log.d( LOG_TAG, "sampling activated" );
					samplingServiceActivated = true;
					walkingTV.setVisibility( View.VISIBLE );
					runningTV.setVisibility( View.VISIBLE );
					shakingTV.setVisibility( View.VISIBLE );
					startSamplingService();
				} else {
					Log.d( LOG_TAG, "sampling deactivated" );
					samplingServiceActivated = false;
					walkingTV.setVisibility( View.INVISIBLE );
					runningTV.setVisibility( View.INVISIBLE );
					shakingTV.setVisibility( View.INVISIBLE );
					stopSamplingService();
				}
			}
		});
    }

	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState( outState );
		Log.d( LOG_TAG, "onSaveInstanceState" );
		outState.putBoolean( SAMPLING_SERVICE_ACTIVATED_KEY, samplingServiceActivated ); 
		if( walkingText != null )
			outState.putString( WALKINGTEXT_KEY, walkingText );
		if( runningText != null )
			outState.putString( RUNNINGTEXT_KEY, runningText );
		if( shakingText != null )
			outState.putString( SHAKINGTEXT_KEY, shakingText );
	}

	protected void onDestroy() {
		super.onDestroy();
		Log.d( LOG_TAG, "onDestroy" );
		releaseSamplingService();
	}

	private void startSamplingService() {
		if( samplingServiceRunning )	// shouldn't happen
			stopSamplingService();
        Intent i = new Intent();
        i.setClassName( "aexp.accel","aexp.accel.SamplingService" );
        startService( i );
		samplingServiceRunning = true;				
	}

	private void stopSamplingService() {
		Log.d( LOG_TAG, "stopSamplingService" );
		if( samplingServiceRunning ) {
			stopSampling();
			samplingServiceRunning = false;
		}
	}

	private void bindSamplingService() {
		samplingServiceConnection = new SamplingServiceConnection();
		Intent i = new Intent();
		i.setClassName( "aexp.accel", "aexp.accel.SamplingService" );
		bindService( i, samplingServiceConnection, Context.BIND_AUTO_CREATE);
	}

	private void releaseSamplingService() {
		releaseCallbackOnService();
		unbindService( samplingServiceConnection );	  
		samplingServiceConnection = null;
	}

    private void setCallbackOnService() {
		if( samplingService == null )
			Log.e( LOG_TAG, "setCallbackOnService: Service not available" );
		else {
			try {
				samplingService.setCallback( iAccel.asBinder() );
			} catch( DeadObjectException ex ) {
				Log.e( LOG_TAG, "DeadObjectException",ex );
			} catch( RemoteException ex ) {
				Log.e( LOG_TAG, "RemoteException",ex );
			}
		}
	}

    private void releaseCallbackOnService() {
		if( samplingService == null )
			Log.e( LOG_TAG, "releaseCallbackOnService: Service not available" );
		else {
			try {
				samplingService.removeCallback();
			} catch( DeadObjectException ex ) {
				Log.e( LOG_TAG, "DeadObjectException",ex );
			} catch( RemoteException ex ) {
				Log.e( LOG_TAG, "RemoteException",ex );
			}
		}
	}

    private void updateSamplingServiceRunning() {
		if( samplingService == null )
			Log.e( LOG_TAG, "updateSamplingServiceRunning: Service not available" );
		else {
			try {
				samplingServiceRunning = samplingService.isSampling();
			} catch( DeadObjectException ex ) {
				Log.e( LOG_TAG, "DeadObjectException",ex );
			} catch( RemoteException ex ) {
				Log.e( LOG_TAG, "RemoteException",ex );
			}
		}
	}

    private void stopSampling() {
		Log.d( LOG_TAG, "stopSampling" );
		if( samplingService == null )
			Log.e( LOG_TAG, "stopSampling: Service not available" );
		else {
			try {
				samplingService.stopSampling();
			} catch( DeadObjectException ex ) {
				Log.e( LOG_TAG, "DeadObjectException",ex );
			} catch( RemoteException ex ) {
				Log.e( LOG_TAG, "RemoteException",ex );
			}
		}
	}

    private IAccel.Stub iAccel 
				= new IAccel.Stub() {
		public void walk( boolean isWalking, int count ) {
			Log.d( LOG_TAG, "walk: isWalking: "+isWalking+"; count: "+count );
			StringBuilder b = new StringBuilder();
			b.append( "Walking " );
			if( isWalking )
				b.append( "detected " );
			else
				b.append( "not detected " ); 
			b.append( "; step count: "+Integer.toString( count ) );
			walkingText = new String( b );
			walkingTV.setText( walkingText );
		}

		public void run( boolean isRunning, int count ) {
			Log.d( LOG_TAG, "run: isRunning: "+isRunning+"; count: "+count );
			StringBuilder b = new StringBuilder();
			b.append( "Running " );
			if( isRunning )
				b.append( "detected " );
			else
				b.append( "not detected " ); 
			b.append( "; step count: "+Integer.toString( count ) );
			runningText = new String( b );
			runningTV.setText( runningText );
		}

		public void shake( boolean isShaking, int count ) {
			Log.d( LOG_TAG, "shake: isShaking: "+isShaking+"; count: "+count );
			StringBuilder b = new StringBuilder();
			b.append( "Shaking " );
			if( isShaking )
				b.append( "detected " );
			else
				b.append( "not detected " ); 
			b.append( "; shake count: "+Integer.toString( count ) );
			shakingText = new String( b );
			shakingTV.setText( shakingText );
		}
    };

    private ISamplingService samplingService = null;
    private SamplingServiceConnection samplingServiceConnection = null;
	private boolean samplingServiceRunning = false;
	private boolean samplingServiceActivated = false;
	private TextView walkingTV;
	private TextView runningTV;
	private TextView shakingTV;
	private String walkingText = null;
	private String runningText = null;
	private String shakingText = null;

    class SamplingServiceConnection implements ServiceConnection {
        public void onServiceConnected(ComponentName className, 
			IBinder boundService ) {
        	samplingService = ISamplingService.Stub.asInterface((IBinder)boundService);
	    	setCallbackOnService();
			updateSamplingServiceRunning();
		 	Log.d( LOG_TAG,"onServiceConnected" );
        }

        public void onServiceDisconnected(ComponentName className) {
        	samplingService = null;
			Log.d( LOG_TAG,"onServiceDisconnected" );
        }
    };


}
